package model;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

public class ContratoDAO
{
	public void incluir(Contrato c) throws SQLException
	{
		Statement comando = DBConnection.getInstancia().conn.createStatement();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String query = "INSERT INTO Contrato (numero, assinatura, situacao, anterior, referencia) VALUES (";
		query += Integer.toString(c.getNumero()) + ", ";
		query += "'" + sdf.format(new Date(c.getAssinatura().getTimeInMillis())) + "', ";
		query += "'" + c.getSituacao() + "', ";
		if (c.getAnterior() != null)
			query += "'" + c.getAnterior().getNumero() + "', ";
		else
			query += "null,";
		query += "'" + c.getReferencia().getReferencia() + "')";
		comando.executeUpdate(query);
	}

	 public void alterar(Contrato contrato, boolean designacao) throws SQLException
	{
		Statement comando = DBConnection.getInstancia().conn.createStatement();
		String query = "";
		if (designacao)	// Somente em caso de designação de acompanhadores
		{
			ResultSet rs;
			query += "SELECT COUNT(*) as existente FROM contrato";
			query += " WHERE numero = " + Integer.toString(contrato.getNumero());
			query += " AND matricula = " + Integer.toString(contrato.getAcompanhador().getMatricula());
			rs = comando.executeQuery(query);
			if (rs.next())
			{
				// Somente fazer a designação do acompanhador ao contrato caso ainda não exista tal vinculação
				if (rs.getInt("existente") == 0)
				{
					query = "UPDATE contrato SET matricula = " + contrato.getAcompanhador().getMatricula() + " WHERE numero = " + contrato.getNumero();
					comando.executeUpdate(query);					
				}
			}
		}
		else
		{
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			query = "UPDATE Contrato SET ";
			query += "assinatura  = '"
					+ sdf.format(new Date(contrato.getAssinatura().getTimeInMillis()))
					+ "', ";
			query += "situacao = '" + contrato.getSituacao() + "', ";
			query += "anterior = "
					+ (contrato.getAnterior() == null ? " null" : "'"
							+ contrato.getAnterior().getNumero() + "'") + ", ";
			query += "referencia = '" + contrato.getReferencia().getReferencia() + "' ";
			query += "WHERE numero  = " + contrato.getNumero();
			comando.executeUpdate(query);
		}
	}

	public void excluir(Contrato contrato) throws SQLException
	{
		Statement comando = DBConnection.getInstancia().conn.createStatement();
		String query = "DELETE FROM Contrato WHERE numero = " + contrato.getNumero();
		comando.executeUpdate(query);
	}

	/*
	 * public Contrato consultar(int numero) throws SQLException {
	 * 
	 * Statement comando = DBConnection.getInstancia().conn.createStatement();
	 * ResultSet rs;
	 * 
	 * ContratoDAO cd = new ContratoDAO(); ProjetoDAO pd = new ProjetoDAO();
	 * FuncionarioDAO fd = new FuncionarioDAO();
	 * 
	 * Contrato c = null;
	 * 
	 * String query = "select * from contrato c where c.numero = " + numero;
	 * 
	 * rs = comando.executeQuery(query);
	 * 
	 * while (rs.next()) { c = new Contrato(); c.setNumero(rs.getInt("numero"));
	 * Calendar data = Calendar.getInstance();
	 * data.setTime(rs.getDate("assinatura")); c.setAssinatura(data);
	 * c.setSituacao(rs.getString("situacao"));
	 * 
	 * ArrayList<Contrato> anterior = new ArrayList<Contrato>(); anterior =
	 * cd.consultar(new Contrato(rs.getInt("numero")), true); if
	 * (anterior.size() == 0) c.setAnterior(null); else
	 * c.setAnterior(anterior.get(0));
	 * 
	 * ArrayList<Projeto> referencia = new ArrayList<Projeto>(); referencia =
	 * pd.consultar(new Projeto(rs.getString("referencia")), true); if
	 * (referencia.size() == 0) c.setReferencia(null); else
	 * c.setReferencia(referencia.get(0));
	 * 
	 * ArrayList<Funcionario> funcionario = new ArrayList<Funcionario>();
	 * funcionario = fd.consultar(new Funcionario(rs.getInt("matricula")),
	 * true); if (funcionario.size() == 0) c.setMatricula(null); else
	 * c.setMatricula(funcionario.get(0)); } return c; }
	 */

	public ArrayList<Contrato> consultar(Contrato contrato, boolean peloNumero) throws SQLException
	{
		Statement comando = DBConnection.getInstancia().conn.createStatement();
		ArrayList<Contrato> retorno = new ArrayList<Contrato>();
		ResultSet rs;

		ContratoDAO cd = new ContratoDAO();
		ProjetoDAO pd = new ProjetoDAO();

		try
		{
			String query = "SELECT c.* FROM contrato c inner join projeto p on c.referencia = p.referencia inner join cliente cli on cli.cnpj = p.cnpj WHERE 1 = 1";
			if (peloNumero)
			{
				query += " AND numero = " + contrato.getNumero();
			}
			else
			{
				if (contrato != null)
				{
					if (contrato.getNumero() != 0)
						query += " AND numero = " + contrato.getNumero();
					if (contrato.getReferencia() != null)
					{
						if (contrato.getReferencia().getReferencia() != null)
							query += " and lower(p.referencia) LIKE lower('%" + contrato.getReferencia().getReferencia() + "%')";
						if (contrato.getReferencia().getCliente() != null)
							if ((contrato.getReferencia().getCliente().getCnpj() != null))
								query += " and cli.cnpj = '" + contrato.getReferencia().getCliente().getCnpj() + "'";
					}
					if (contrato.getAcompanhador() != null)
					{
						if (contrato.getAcompanhador() != null && contrato.getAcompanhador().getMatricula() != 0)
							query += " AND matricula = " + Integer.toString(contrato.getAcompanhador().getMatricula());
					}
					if (contrato.getSituacao() != null)
						query += " AND lower(situacao) = lower('" + contrato.getSituacao() + "')";
				}
			}
			//System.out.println(query);
			rs = comando.executeQuery(query);
			while (rs.next())
			{
				// Construir contrato
				Contrato c = new Contrato();
				c.setNumero(rs.getInt("numero"));
				String d = rs.getString("assinatura");
				int ano = Integer.parseInt(d.substring(0, 4));
				int mes = Integer.parseInt(d.substring(5, 7)) - 1;
				int dia = Integer.parseInt(d.substring(8, 10));
				Calendar data = new GregorianCalendar(ano, mes, dia);
				c.setAssinatura(data);
				c.setSituacao(rs.getString("situacao"));
				c.setAcompanhador(new Funcionario(rs.getInt("matricula")));

				ArrayList<Contrato> anterior = cd.consultar((new Contrato(rs.getInt("anterior"))), true);
				if (anterior.size() == 0)
					c.setAnterior(null);
				else
					c.setAnterior(anterior.get(0));
				ArrayList<Projeto> referencia = pd.consultar((new Projeto(rs.getString("referencia"))), true);
				if (referencia.size() == 0)
					c.setReferencia(null);
				else
					c.setReferencia(referencia.get(0));
				retorno.add(c);
			}
		}
		catch (SQLException e) 
		{
			e.printStackTrace();
		}
		return retorno;
	}

	public ArrayList<Garantia> getGarantias(Contrato contrato) throws SQLException
	{
		Statement comando = DBConnection.getInstancia().conn.createStatement();
		ArrayList<Garantia> retorno = new ArrayList<Garantia>();
		ResultSet rs;
		try
		{
			BemDAO objBDAO = new BemDAO();
			String query = "SELECT * FROM garantia WHERE 1 = 1";
			if (contrato.getNumero() != 0)
				query += " AND contrato = " + Integer.toString(contrato.getNumero());
			query += " ORDER BY clausula";
			rs = comando.executeQuery(query);
			while (rs.next())
			{
				Garantia garantia = new Garantia();
				garantia.setContrato(new Contrato(rs.getInt("contrato")));
				Bem bem = objBDAO.consultar(new Bem(rs.getInt("id_bem")), true).get(0);
				garantia.setBem(bem);
				garantia.setClausula(rs.getString("clausula"));
				garantia.setValor(rs.getFloat("valor"));
				retorno.add(garantia);
			}
		}
		catch (SQLException e) 
		{
			e.printStackTrace();
		}
		return retorno;
	}

	public ArrayList<Map<String, String>> getLista(ArrayList<String> p)	throws SQLException
	{
		Statement comando = DBConnection.getInstancia().conn.createStatement();
		ArrayList<Map<String, String>> retorno = new ArrayList<Map<String, String>>();
		ResultSet rs;

		SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");	
		try
		{
			String query = "";
			query += "select ";
			query += "c.numero, ";
			query += "p.referencia, ";
			query += "p.titulo, ";
			query += "cl.cnpj, ";
			query += "cl.razao_social, ";
			query += "f.matricula, ";
			query += "f.nome, ";
			query += "c.situacao, ";
			query += "b.descricao, ";
			query += "c.assinatura ";
			query += "from ";
			query += "contrato c inner join projeto p ";
			query += "on c.referencia = p.referencia ";
			query += "inner join cliente cl ";
			query += "on p.cnpj = cl.cnpj ";
			query += "left join funcionario f ";
			query += "on c.matricula = f.matricula ";
			query += "left join garantia g ";
			query += "on c.numero = g.contrato ";
			query += "left join bem b ";
			query += "on g.id_bem = b.id_bem ";
			query += "where 1 = 1 ";

			// order dos parametros: 0-cliente 1-contrato 2-situacao e
			// 3-acompanhador

			if (p.size() > 0)
			{
				if (!(p.get(0).equals(""))) // cliente
					query += " and cl.cnpj = '" + p.get(0) + "'";

				if (!(p.get(1).equals(""))) // contrato
					query += " and c.numero = " + p.get(1);

				if (!(p.get(2).equals(""))) // situacao
					query += " and upper(c.situacao) = upper('" + p.get(2) + "')";

				if (!(p.get(3).equals(""))) // acompanhador
					query += " and f.matricula = " + p.get(3);
			}
			
			rs = comando.executeQuery(query);
			while (rs.next()) 
			{	
				Map<String, String> linha = new HashMap<String, String>();
				
				linha.put("numero",       rs.getString("numero"));       // 0
				linha.put("referencia",   rs.getString("referencia"));   // 1
				linha.put("titulo",       rs.getString("titulo"));       // 2
				linha.put("cnpj",         rs.getString("cnpj"));         // 3
				linha.put("razao_social", rs.getString("razao_social")); // 4
				linha.put("matricula",    rs.getString("matricula"));    // 5
				linha.put("nome",         rs.getString("nome"));         // 6
				linha.put("situacao",     rs.getString("situacao"));     // 7
				linha.put("descricao",    rs.getString("descricao"));    // 8
                String d = rs.getString("assinatura");
				linha.put("assinatura",   sdf.format(new Date( 
						                                      new GregorianCalendar(Integer.parseInt(d.substring(0, 4)),
						                                    		                Integer.parseInt(d.substring(5, 7)) - 1,
						                                    		                Integer.parseInt(d.substring(8, 10))).getTimeInMillis())));
				retorno.add(linha);
			}
			
		}
		catch (SQLException e) 
		{
			e.printStackTrace();
		}
		return retorno;
	}
}